<template>
  <div>
    <div ref="graphContainer" style="width: 100%; height: 600px; border: 1px solid #eee; border-radius: 4px;"></div>
    
    <div class="graph-notes">
      <div class="note-title">图例说明：</div>
      <div class="notes-container">
        <div v-for="(cat, key) in categoryMap" :key="key" class="note-item">
          <span class="color-dot" :style="{ backgroundColor: cat.color }"></span>
          <span class="node-type">{{ cat.label }}</span>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, onUnmounted, watch } from 'vue';
import * as echarts from 'echarts';
import { knowledgeGraphApi } from '@/api/recommend.js';
import { typesApi } from '@/api/type.js'; // 引入类型接口

const props = defineProps({
  goodsId: {
    type: [Number, String],
    required: true
  }
});

const graphContainer = ref(null);
let chart = null;
const loading = ref(false);
let lastGoodsId = null;
let resizeTimeout = null;
let typeMapping = {}; // 存储类型ID到类型名称的映射

// 定义节点类型对应的颜色、图标和中文名称
const categoryMap = {
  'Goods': { color: '#5470c6', symbol: 'circle', label: '工艺品' },
  'Region': { color: '#91cc75', symbol: 'triangle', label: '地区' },
  'Period': { color: '#fac858', symbol: 'diamond', label: '朝代' },
  'CraftSchool': { color: '#ee6666', symbol: 'rect', label: '工艺流派' },
  'Culture': { color: '#73c0de', symbol: 'roundRect', label: '文化' },
  'HistoricalFigure': { color: '#3ba272', symbol: 'pin', label: '历史人物' },
  'HistoricalEvent': { color: '#fc8452', symbol: 'arrow', label: '历史事件' }
};

// 在组件挂载时获取类型映射数据
const fetchTypeMapping = async () => {
  try {
    const response = await typesApi();
    if (response.code === 200 && response.data) {
      // 创建类型ID到名称的映射
      typeMapping = response.data.reduce((map, type) => {
        map[type.id] = type.name;
        return map;
      }, {});
      console.log('类型映射数据加载成功:', typeMapping);
    }
  } catch (error) {
    console.error('获取类型映射数据失败:', error);
  }
};

// 格式化节点数据为ECharts格式
const formatNodes = (nodes) => {
  return nodes.map(node => {
    const category = categoryMap[node.label] || { color: '#bbb', symbol: 'circle', label: '其他' };
    
    // 处理Neo4j返回的ID对象格式
    let nodeId;
    if (typeof node.id === 'object' && node.id.low !== undefined) {
      nodeId = node.id.low.toString();
    } else {
      nodeId = String(node.id);
    }
    
    // 获取节点名称，如果没有name属性则使用类型标签+ID
    const nodeName = node.properties.name || category.label + '-' + nodeId;
    
    return {
      id: nodeId,
      name: nodeName,
      symbolSize: node.level === 0 ? 35 : 25,
      value: node.properties,
      category: category.label, // 使用中文类型标签
      itemStyle: {
        color: category.color
      },
      symbol: category.symbol
    };
  });
};

// 格式化关系数据为ECharts格式
const formatLinks = (relationships) => {
  return relationships.map(rel => {
    // 处理Neo4j返回的ID对象格式
    let sourceId, targetId;
    
    if (typeof rel.source === 'object' && rel.source.low !== undefined) {
      sourceId = rel.source.low.toString();
    } else {
      sourceId = String(rel.source);
    }
    
    if (typeof rel.target === 'object' && rel.target.low !== undefined) {
      targetId = rel.target.low.toString();
    } else {
      targetId = String(rel.target);
    }
    
    return {
      source: sourceId,
      target: targetId,
      name: rel.type,
      value: rel.properties || {}
    };
  });
};

// 获取知识图谱数据
const fetchGraphData = async () => {
  if (!props.goodsId) return;
  
  // 避免重复加载相同商品的知识图谱
  if (lastGoodsId === props.goodsId && chart) {
    return;
  }
  
  lastGoodsId = props.goodsId;
  loading.value = true;
  
  try {
    const response = await knowledgeGraphApi(props.goodsId)
    const graphData = response.data

    if (!graphData ||
        (!graphData.nodes || !graphData.nodes.length) &&
        (!graphData.relationships || !graphData.relationships.length)) {
      showEmptyGraph();
    } else {
      initGraph(graphData);
    }
  } catch (error) {
    showEmptyGraph();
  } finally {
    loading.value = false;
  }
};

// 显示空图表
const showEmptyGraph = () => {
  if (!graphContainer.value) return;
  
  if (!chart) {
    chart = echarts.init(graphContainer.value);
  }
  
  const option = {
    title: {
      text: '暂无知识图谱数据',
      left: 'center',
      top: 'center',
      textStyle: {
        fontSize: 20,
        color: '#999'
      }
    }
  };
  
  chart.setOption(option);
};

// 初始化图表
const initGraph = (data) => {
  if (!graphContainer.value) return;
  
  if (!chart) {
    chart = echarts.init(graphContainer.value);
  }
  
  const nodes = formatNodes(data.nodes || []);
  const links = formatLinks(data.relationships || []);
  
  // 使用中文标签创建图例分类
  const categories = Object.keys(categoryMap).map(key => ({
    name: categoryMap[key].label, // 使用中文标签
    itemStyle: {
      color: categoryMap[key].color
    }
  }));
  
  const option = {
    title: {
      text: '工艺品知识图谱',
      top: 'top',
      left: 'center'
    },
    tooltip: {
      formatter: function(params) {
        if (params.dataType === 'node') {
          const data = params.data;
          let html = `<div style="font-weight:bold;font-size:14px;">${data.name}</div>`;
          
          if (data.value) {
            html += '<div style="margin-top:8px;">';
            
            // 属性名称映射
            const propNameMap = {
              'id': 'ID',
              'name': '名称',
              'type': '类型',
              'content': '内容',
              'period': '朝代',
              'region': '地区',
              'date': '日期',
              'description': '描述',
              'cultural_background': '文化背景',
              'craft_process': '工艺流程',
              'cultural_value': '文化价值',
              'value': '值'
            };
            
            // 需要排除的属性
            const excludeProps = ['cover', 'id', 'name'];
            
            Object.keys(data.value).forEach(key => {
              // 排除不需要显示的属性
              if (!excludeProps.includes(key) && data.value[key]) {
                const propName = propNameMap[key] || key;
                let propValue = data.value[key];
                
                // 特殊处理type字段，使用typeMapping映射
                if (key === 'type' && typeMapping[propValue]) {
                  propValue = typeMapping[propValue];
                }
                
                // 如果值过长则截断
                if (typeof propValue === 'string' && propValue.length > 50) {
                  propValue = propValue.substring(0, 50) + '...';
                }
                
                html += `<div style="margin-top:3px;"><span style="color:#999;">${propName}:</span> ${propValue}</div>`;
              }
            });
            
            html += '</div>';
          }
          return html;
        } else if (params.dataType === 'edge') {
          // 翻译边的关系类型显示
          const edgeTypeMap = {
            'RELATED_TO': '相关',
            'RELATED_TO_FIGURE': '关联人物',
            'RELATED_TO_EVENT': '关联事件',
            'BELONGS_TO_REGION': '所属地区',
            'BELONGS_TO_PERIOD': '所属朝代',
            'BELONGS_TO_SCHOOL': '所属流派',
            'CULTURAL_RELATION': '文化关联',
            'HAS_HISTORY': '历史背景'
          };
          const edgeType = edgeTypeMap[params.name] || params.name;
          
          // 处理关系的其他属性
          let html = `<div style="font-weight:bold;">${edgeType}</div>`;
          
          if (params.data.value && Object.keys(params.data.value).length > 0) {
            html += '<div style="margin-top:5px;">';
            Object.keys(params.data.value).forEach(key => {
              if (key === 'reasons' && Array.isArray(params.data.value[key])) {
                html += `<div>原因: ${params.data.value[key].join(', ')}</div>`;
              } else {
                html += `<div>${key}: ${params.data.value[key]}</div>`;
              }
            });
            html += '</div>';
          }
          
          return html;
        }
      }
    },
    legend: {
      data: categories.map(c => c.name),
      orient: 'vertical',
      left: 'left',
      top: 'middle',
      textStyle: {
        fontSize: 12
      },
      itemWidth: 15,
      itemHeight: 10,
      itemGap: 8,
      formatter: function(name) {
        // 限制图例文字长度
        return name.length > 4 ? name.substring(0, 4) + '..' : name;
      }
    },
    animationDuration: 1500,
    animationEasingUpdate: 'quinticInOut',
    series: [
      {
        type: 'graph',
        layout: 'force',
        data: nodes,
        links: links,
        categories: categories,
        roam: true,
        label: {
          show: true,
          position: 'right',
          formatter: '{b}',
          fontSize: 12
        },
        force: {
          repulsion: 200,
          edgeLength: 120
        },
        lineStyle: {
          color: 'source',
          curveness: 0.3
        },
        emphasis: {
          focus: 'adjacency',
          lineStyle: {
            width: 4
          }
        }
      }
    ]
  };
  
  chart.setOption(option);
  
  // 响应窗口变化
  window.addEventListener('resize', handleResize);
};

// 添加防抖处理的resize函数
const handleResize = () => {
  if (resizeTimeout) {
    clearTimeout(resizeTimeout);
  }
  
  resizeTimeout = setTimeout(() => {
    if (chart) {
      chart.resize();
    }
  }, 100);
};

// 监听goodsId变化
watch(() => props.goodsId, (newVal) => {
  if (newVal) {
    fetchGraphData();
  }
});

onMounted(() => {
  fetchTypeMapping();
  fetchGraphData();
});

onUnmounted(() => {
  if (chart) {
    chart.dispose();
    chart = null;
  }
  
  if (resizeTimeout) {
    clearTimeout(resizeTimeout);
  }
  
  window.removeEventListener('resize', handleResize);
});
</script>

<style scoped>
.graph-notes {
  margin-top: 10px;
  padding: 10px;
  border-top: 1px solid #eee;
  font-size: 14px;
}

.note-title {
  margin-bottom: 8px;
  font-weight: bold;
}

.notes-container {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
}

.note-item {
  display: flex;
  align-items: center;
}

.color-dot {
  display: inline-block;
  width: 10px;
  height: 10px;
  margin-right: 5px;
  border-radius: 50%;
}

.node-type {
  font-size: 13px;
}

.legend-item {
  display: flex;
  align-items: center;
  margin-bottom: 8px;
}

.legend-color {
  width: 15px;
  height: 15px;
  margin-right: 8px;
  border-radius: 3px;
}
</style> 